/*
 *
 *   Copyright (C) 2005 by Raymond Huang
 *   plushuang at users.sourceforge.net
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  In addition, as a special exception, the copyright holders give
 *  permission to link the code of portions of this program with the
 *  OpenSSL library under certain conditions as described in each
 *  individual source file, and distribute linked combinations
 *  including the two.
 *  You must obey the GNU Lesser General Public License in all respects
 *  for all of the code used other than OpenSSL.  If you modify
 *  file(s) with this exception, you may extend this exception to your
 *  version of the file(s), but you are not obligated to do so.  If you
 *  do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source
 *  files in the program, then also delete it here.
 *
 */

#ifndef __QUEUE_NODE_H
#define __QUEUE_NODE_H

#include <urlglib/download_node.h>

#ifdef __cplusplus
extern "C" {
#endif

#define QUEUE_NODE(obj)           ((QueueNode*)(obj))
#define QUEUE_NODE_TAG            "queue_node"

typedef struct _QueueNode           QueueNode;
typedef void (*QueueNodeAddFunc)  (QueueNode* qnode, DownloadNode* dnode);
typedef void (*QueueNodeCallback) (QueueNode* qnode, DownloadNode* dnode,
                                   int nth, gpointer data);
struct _QueueNode {
	BASE_NODE_FIELDS;

	GSList*              changed_signal;
	QueueNodeAddFunc     add;
};

QueueNode* queue_node_new ();
QueueNode* queue_node_new_reverse ();

#define queue_node_ref(qnode)    base_node_ref (BASE_NODE(qnode))
#define queue_node_unref(qnode)  base_node_unref (BASE_NODE(qnode))

#define queue_node_first_download(qnode)  (DownloadNode*)base_node_first_child(BASE_NODE (qnode))
#define queue_node_last_download(qnode)   (DownloadNode*)base_node_last_child(BASE_NODE (qnode))
#define queue_node_nth_download(o,n)      (DownloadNode*)base_node_nth_child(BASE_NODE (o), n)
#define queue_node_get_category(qnode)    (CategoryNode*)base_node_parent(BASE_NODE (qnode))
#define queue_node_download_position(q,d) base_node_child_position(BASE_NODE(q), BASE_NODE(d))
#define queue_node_n_download(q)          base_node_n_children (BASE_NODE (q))

#define queue_node_append(qn,dn)    base_node_append (BASE_NODE (qn), BASE_NODE (dn))
#define queue_node_prepend(qn,dn)   base_node_prepend (BASE_NODE (qn), BASE_NODE (dn))
#define queue_node_unlink(qnode)    base_node_unlink (BASE_NODE(qnode))
#define queue_node_insert_before(qn,s,dn)  base_node_insert_before (BASE_NODE (qn), BASE_NODE (s), BASE_NODE (dn))
#define queue_node_insert_after(qn,s,dn)   base_node_insert_after  (BASE_NODE (qn), BASE_NODE (s), BASE_NODE (dn))
void    queue_node_add (QueueNode* qnode, DownloadNode* dnode);
void    queue_node_remove_after_nth (QueueNode* qnode, int n);

DownloadNode* queue_node_find (QueueNode* qnode, DownloadNodeState state, DownloadNode* after_sibling);

gboolean queue_node_is_waiting (QueueNode* qnode);
gboolean queue_node_is_completed (QueueNode* qnode);
gboolean queue_node_is_recycled (QueueNode* qnode);

// notify callback & setup functions ---------------------------------

#define queue_node_inserted_connect(qnode, fn, data)    \
            base_node_inserted_connect (BASE_NODE (qnode), (BaseNodeCallback)fn, data)
#define queue_node_inserted_disconnect(qnode, ndata)    \
            base_node_inserted_disconnect (BASE_NODE (qnode), ndata)

#define queue_node_removed_connect(qnode, fn, data)    \
            base_node_removed_connect (BASE_NODE (qnode), (BaseNodeCallback)fn, data)
#define queue_node_removed_disconnect(qnode, ndata)     \
            base_node_removed_disconnect (BASE_NODE (qnode), ndata)

#define queue_node_changed_connect(qnode, fn, data)    \
            urlglib_signal_connect (&(qnode)->changed_signal, (BaseNodeCallback)fn, data)
#define queue_node_changed_disconnect(qnode, ndata)    \
            urlglib_signal_disconnect (&(qnode)->changed_signal, ndata)

#define queue_node_changed(qnode, dnode)    \
            base_node_signal_emit (&(qnode)->changed_signal, BASE_NODE (qnode), BASE_NODE (dnode))

// config writer & parser --------------------------------------------
int  queue_node_parser_attr (const gchar**     attr_names,
                             const gchar**     attr_values);
void queue_node_write_conf (QueueNode* qnode, ConfWriter* cw);
// parser
extern const GMarkupParser queue_node_parser;

#ifdef __cplusplus
}
#endif

#endif  // End of __QUEUE_NODE_H
